﻿using Com.Lancetinc.Evs.Helpers;
using Com.Lancetinc.Evs.Windows;
using MahApps.Metro.Actions;
using MahApps.Metro.Controls;
using System;
using System.Threading.Tasks;
using System.Windows;

namespace Com.Lancetinc.Evs.Controls
{
    public class SettingFlyout : Flyout
    {
        public SettingFlyout()
        {
            this.Theme = FlyoutTheme.Light;
            AllowFocusElement = false;
            AreAnimationsEnabled = true;
            Position = Position.Left;
            this.Style = (Style)FindResource("LevsSettingFlyout");
            this.ClosingFinished += SettingFlyout_ClosingFinished;
        }

        private ISettingFlyoutControl _currentCtrl;
        private IDisposable _onClose;

        public void ShowAbout()
        {
            ShowControl(new AboutControl());
        }

        public void ShowSetting()
        {
            ShowControl(new SettingControl());
        }

        public async Task CloseFlyout()
        {
            if (!await CheckClose())
                return;

            this.IsOpen = false;
        }

        public async Task<bool> CheckClose()
        {
            if (Content is ISettingFlyoutControl c)
            {
                if (!await c.ConfirmCloseAsync())
                    return false;
            }
            return true;
        }

        private void SettingFlyout_ClosingFinished(object sender, RoutedEventArgs e)
        {
            _onClose?.Dispose();
            _onClose = null;
            _currentCtrl = null;
        }

        private void ShowControl(ISettingFlyoutControl ctrl)
        {
            IsPinned = ctrl.IsPinned;
            Header = ctrl.Title;
            _currentCtrl = ctrl;
            this.Content = ctrl;
            SetWidth();
            this.IsOpen = true;
            _onClose = new DelegateDisposable(() =>
            {
                Content = null;
                Header = null;
                IsPinned = false;
            });
        }

        private void SetWidth()
        {
            var w = _currentCtrl.WidthRequest;
            if (!double.IsNaN(w))
                Width = w;
            else
                Width = 450;
        }
    }

    public class SettingCloseFlyoutAction : CloseFlyoutAction
    {
        private Flyout associatedFlyout;
        private Flyout AssociatedFlyout => this.associatedFlyout ??= this.AssociatedObject.TryFindParent<Flyout>();

        protected override async void Invoke(object parameter)
        {
            if (this.AssociatedObject == null || this.AssociatedObject is { IsEnabled: false })
            {
                return;
            }

            if (AssociatedFlyout is SettingFlyout settingFlyout)
            {
                if (!await settingFlyout.CheckClose())
                    return;
            }

            base.Invoke(parameter);
        }
    }

    public interface ISettingFlyoutControl
    {
        string Title { get; }

        /// <summary>
        /// 点击外面是否可以关闭？
        /// </summary>
        bool IsPinned { get; }

        double WidthRequest { get; }

        Task<bool> ConfirmCloseAsync();
    }
}